package com.demo.server.servce;

import com.alibaba.fastjson.JSONObject;
import com.demo.server.core.Environment;
import com.demo.server.pojo.Message;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.util.Iterator;

/**
 * @author:谢君臣
 * @Date:2021/7/26-19:08
 * @version:1.0
 * @function:
 */
public class Server implements Runnable {
    private Environment environment = Environment.newInstance();
    private MessagePush messagePush;
    private Selector selector;
    private ServerSocketChannel channel;

    public Server() {
        this.messagePush = new MessagePushImpl();
        try {
            //1.获取通道
            channel = ServerSocketChannel.open();
            //2.切换为非阻塞模式
            channel.configureBlocking(false);
            //3.绑定端口
            channel.bind(new InetSocketAddress(environment.getPort()));
            //4.获取选择器
            selector = Selector.open();
            //5.将通道注册的选择器
            channel.register(selector, SelectionKey.OP_ACCEPT);
            //6.轮询selector已经就绪的事件
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void run() {
        System.out.println("========服务器端启动=========");
        try {
            while (selector.select() > 0) {
                Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
                while (iterator.hasNext()) {
                    SelectionKey selectionKey = iterator.next();
                    if (selectionKey.isAcceptable()) {
                        SocketChannel accept = channel.accept();
                        accept.configureBlocking(false);
                        accept.register(selector, SelectionKey.OP_READ);
                    } else if (selectionKey.isReadable()) {
                        readClientData(selectionKey);
                    }
                    iterator.remove();
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    private void readClientData(SelectionKey selectionKey){
        SocketChannel schannel = null;
        try {
            StringBuilder stringBuilder = new StringBuilder();
            schannel = (SocketChannel) selectionKey.channel();
            ByteBuffer buffer = ByteBuffer.allocate(1024);
            int len = 0;
            while ((len = schannel.read(buffer)) != -1) {
                buffer.flip();
                schannel.read(buffer);
                buffer.clear();
                stringBuilder.append(new String(buffer.array(), 0, len));
            }
            Message message = JSONObject.parseObject(stringBuilder.toString(), Message.class);
            messagePush.push(message,schannel,selector);
        } catch (IOException e) {
            // 当前客户端已经关闭
            try {
                System.out.println("客户端"+schannel.getLocalAddress()+"已经离线");
                selectionKey.cancel();
                schannel.close();
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    }
}
